#!/usr/bin/env python
# encoding: utf-8
"""
binpack.py

Created by 黄 冬 on 2007-12-12.
Copyright (c) 2007 __MyCompanyName__. All rights reserved.
"""

from struct import *
import logging.config

log = logging.getLogger('xbaytable.utils.binpack')

from xbaytable.conf import *

def unpackbody(command,msg):
    """按command生成对应的msg内容解析
    参数说明：
    command 要解包的command_id的定义，可以见xbaytable.conf中的定义
    msg 对端发来的msg二进制流"""
    #log.debug('cmd is %s,fmt is %s,msg is %s'%(command['command_name'],command['body_fmt'], repr(msg)))
    log.debug('cmd is %s,fmt is %s'%(command['command_name'],command['body_fmt']))
    if (command['body_dynamic']) :
        return eval('unpack_%s(command.copy(),msg)'%command['command_name'])
    else:
        return unpack(command['body_fmt'],msg)

def unpackhead(msg):
    """从msg中取出head中的pkg_size、command_id和sequence_id"""
    log.debug('unpack head %s'%repr(msg))
    command_id,sequence_id=unpack('!HH',msg)
    try:
        return TABLE_COMMAND[command_id],sequence_id
    except KeyError:
        log.error('error head:%s'%repr(msg))

def genbody(command , *msg):
    """按command生成数据包的内容。当生成body时如果发现该command的内容是动态定义，哪么它会调用gen_[command_id]方法进body的行动态定义
    参数说明：
    command 要打包的command_id的定义，可以见xbaytable.conf中的定义
    *msg 按规范定义的msg body内容，详见 http://code.google.com/p/xbaytable/wiki/Specification """
    #log.debug("cmd is %s,fmt is %s,msg is %s"%(command['command_name'],command['body_fmt'], msg))
    if (command['body_dynamic']) :
        return eval('gen_%s(command.copy(), *msg)'%command['command_name'])
    else:
        if(len(command['body_fmt'])==0):
            return ''
        else:
            return pack(command['body_fmt'],*msg)

def genhead(command, sequence_id, body_length):
    """生成包头"""
    #return pack('!HHH',body_length+6,command['command_id'],sequence_id)
    return pack('!HH',command['command_id'],sequence_id)

def genmsg(command, sequence_id, *msg):
    """生成消息体
    参数说明：
    command 要打包的command_id的定义，可以见xbaytable.conf中的定义
    sequence_id 打包的sequence_id
    *msg 按规范定义的msg body内容，详见 http://code.google.com/p/xbaytable/wiki/Specification """
    body = genbody(command, *msg)
    head = genhead(command, sequence_id, len(body))
    return head+body

def gen_table_set(command, *msg):
    """生成table_set的动态body定义"""
    command['body_fmt'] = command['body_fmt']%{'name_len':msg[0],'value_len':len(msg[2])} 
    command['body_dynamic'] = False
    return genbody(command, *msg)

def unpack_table_set(command,msg):
    """对table_set的body进行动态解包"""
    name_len=unpack('!H',msg[0:2])[0]
    value_len=len(msg)-2-name_len
    command['body_fmt'] = command['body_fmt']%{'name_len':name_len,'value_len':value_len} 
    command['body_dynamic'] = False
    return unpackbody(command,msg)

def gen_table_append(command, *msg):
    """生成table_append的动态body定义"""
    command['body_fmt'] = command['body_fmt']%{'name_len':msg[0],'value_len':len(msg[2])} 
    command['body_dynamic'] = False
    return genbody(command, *msg)

def unpack_table_append(command,msg):
    """对table_append的body进行动态解包"""
    name_len=unpack('!H',msg[0:2])[0]
    value_len=len(msg)-2-name_len
    command['body_fmt'] = command['body_fmt']%{'name_len':name_len,'value_len':value_len} 
    command['body_dynamic'] = False
    return unpackbody(command,msg)

def gen_table_del(command, *msg):
    """生成table_del的动态body定义"""
    command['body_fmt'] = command['body_fmt']%{'name_len':len(msg[0])} 
    command['body_dynamic'] = False
    return genbody(command, *msg)

def unpack_table_del(command,msg):
    """对table_del的body进行动态解包，由于它只有一个内容，所以返回的值会做一个[0]处理"""
    name_len=len(msg)
    command['body_fmt'] = command['body_fmt']%{'name_len':name_len}
    command['body_dynamic'] = False
    return unpackbody(command,msg)[0]

def gen_table_del_resp(command, *msg):
    """生成table_del_resp的动态body定义"""
    command['body_fmt'] = command['body_fmt']%{'name_len':len(msg[1])} 
    command['body_dynamic'] = False
    return genbody(command, *msg)

def unpack_table_del_resp(command,msg):
    """对table_del_resp的body进行动态解包"""
    name_len=len(msg)-2
    command['body_fmt'] = command['body_fmt']%{'name_len':len(msg[1])} 
    command['body_dynamic'] = False
    return unpackbody(command,msg)

def gen_table_get(command, *msg):
    """生成table_get的动态body定义"""
    command['body_fmt'] = command['body_fmt']%{'name_len':len(msg[0])} 
    command['body_dynamic'] = False
    return genbody(command, *msg)

def unpack_table_get(command, msg):
    """对table_get的boey进行动态解包"""
    name_len=len(msg)
    command['body_fmt'] = command['body_fmt']%{'name_len':name_len}
    command['body_dynamic'] = False
    return unpackbody(command,msg)[0]

def gen_table_get_resp(command, *msg):
    """生成 table_get_resp的动态body定义"""
    command['body_fmt'] = command['body_fmt']%{'name_len':msg[1],'value_len':len(msg[3])} 
    command['body_dynamic'] = False
    return genbody(command, *msg)

def unpack_table_get_resp(command,msg):
    """对table_get_resp的body进行动态解包"""
    name_len=unpack('!H',msg[2:4])[0]
    log.debug('table_get_resp name_len is %s'%name_len)
    value_len=len(msg)-4-name_len
    log.debug('table_get_resp value_len is %s'%value_len)
    command['body_fmt'] = command['body_fmt']%{'name_len':name_len,'value_len':value_len} 
    command['body_dynamic'] = False
    return unpackbody(command,msg)
